﻿using System;
using System.Windows;
using System.Windows.Input;
using Oxage.Models;

namespace Oxage.Views
{
	public partial class JumpToLineWindow : Window
	{
		#region Constructors
		public JumpToLineWindow()
		{
			InitializeComponent();

			this.Loaded += (sender, e) =>
			{
				input.Focus();
				input.SelectAll();
			};
		}

		public JumpToLineWindow(int currentLineNumber, int maximumLineNumber) : this()
		{
			this.MinimumLineNumber = 1;
			this.MaximumLineNumber = maximumLineNumber;
			this.CurrentLineNumber = currentLineNumber;
		}
		#endregion

		#region Public properties
		public int MinimumLineNumber
		{
			get
			{
				return this.minimumLineNumber;
			}
			set
			{
				this.minimumLineNumber = value;
				min.Text = this.minimumLineNumber.ToString();
			}
		}
		private int minimumLineNumber = 1;
		
		public int MaximumLineNumber
		{
			get
			{
				return this.maximumLineNumber;
			}
			set
			{
				this.maximumLineNumber = value;
				max.Text = this.maximumLineNumber.ToString();
			}
		}
		private int maximumLineNumber = 100;

		public int CurrentLineNumber
		{
			get
			{
				int value = 0;
				if (int.TryParse(input.Text ?? "", out value))
				{
					if (value < this.MinimumLineNumber)
					{
						value = this.MinimumLineNumber;
					}
					else if (value > this.MaximumLineNumber)
					{
						value = this.MaximumLineNumber;
					}
				}
				else
				{
					value = this.MinimumLineNumber;
				}
				return value;
			}
			set
			{
				if (value < this.MinimumLineNumber)
				{
					input.Text = this.MinimumLineNumber.ToString();
				}
				else if (value > this.MaximumLineNumber)
				{
					input.Text = this.MaximumLineNumber.ToString();
				}
				else
				{
					input.Text = value.ToString();
				}
			}
		}
		#endregion

		#region Protected methods
		protected void GoToLine()
		{
			OnJumpToLineRequest(true, this.CurrentLineNumber);
		}
		#endregion

		#region Event handlers
		private void Window_KeyDown(object sender, KeyEventArgs e)
		{
			switch (e.Key)
			{
				case Key.Enter:
					GoToLine();
					Close();
					break;

				case Key.Escape:
					Close();
					break;
			}
		}

		private void OK_Click(object sender, RoutedEventArgs e)
		{
			GoToLine();
			Close();
		}

		private void Close_Click(object sender, RoutedEventArgs e)
		{
			Close();
		}
		#endregion

		#region Static methods
		public static void ShowDialog(int currentLineNumber, int maximumLineNumber, Action<int> callback)
		{
			var window = new JumpToLineWindow(currentLineNumber, maximumLineNumber);
			window.JumpToLineRequest += (sender, e) =>
			{
				if (callback != null && e.Result)
				{
					callback(e.LineNumber);
				}
			};
			window.Show();
		}
		#endregion

		#region Bubble events
		public event EventHandler<JumpToLineEventArgs> JumpToLineRequest;
		protected virtual void OnJumpToLineRequest(bool result, int lineNumber)
		{
			if (JumpToLineRequest != null)
			{
				JumpToLineRequest(this, new JumpToLineEventArgs(result, lineNumber));
			}
		}
		#endregion
	}
}
